import re

from django.http import HttpResponse
from django.shortcuts import render
from app.models.order import Orders, Menu
from app.models.cookbook import *
import json
import os
from django.views.decorators.csrf import csrf_exempt
import re
import uuid
import requests
import xmltodict
import hashlib
import datetime
from django.forms.models import model_to_dict
import html
import threading
import time
from datetime import datetime
# import simplejson



# 引入result.py中定义的数据类型转换工具类和方法
from app.util.result import query_set_to_list, CodeModeDTO, model_to_dict

# 微信支付
# 公众号id
APPID = 'wx4dc97666826255ba'
# 公众号AppSecret
APPSECRET = 'bf576106425a7247b4b219233f1e8aee'
# 商户id
MCH_ID = '1515919861'
# 商户API秘钥
API_KEY = 'UDUsoft78jiudu123tanqin520UDUsof'




# Create your views here.
# 查询菜品价格
def getPriceById(cookbook_id, menu_id):
    a = re.compile('^[0-9a-fA-F]{24}$')
    b = a.search(cookbook_id)
    if not b:
        raise BaseException('cookbook_id无效')
    price = 0.0
    if cookbook_id is None or cookbook_id is "" or menu_id is None or menu_id is "":
        raise BaseException('菜谱参数无效')
    else:
        cookbook = CookBook.objects.get(id=cookbook_id)
        menuList = cookbook.menu
        for food in menuList:
            if food.id == menu_id:
                price = food.price

    return price


# 查询菜品名称
def getNameById(cookbook_id, menu_id):
    a = re.compile('^[0-9a-fA-F]{24}$')
    b = a.search(cookbook_id)
    if not b:
        raise BaseException('cookbook_id无效')
    name = ""
    if cookbook_id is None or cookbook_id is "" or menu_id is None or menu_id is "":
        raise BaseException('菜谱参数无效')
    else:
        cookbook = CookBook.objects.get(id=cookbook_id)
        menuList = cookbook.menu
        for food in menuList:
            if food.id == menu_id:
                name = food.name

    return name


# 查询菜品主图路径
def getUrlById(cookbook_id, menu_id):
    a = re.compile('^[0-9a-fA-F]{24}$')
    b = a.search(cookbook_id)
    if not b:
        raise BaseException('cookbook_id无效')
    pic_url = ""
    if cookbook_id is None or cookbook_id is "" or menu_id is None or menu_id is "":
        raise BaseException('菜谱参数无效')
    else:
        cookbook = CookBook.objects.get(id=cookbook_id)
        menuList = cookbook.menu
        for food in menuList:
            if food.id == menu_id:
                pic_url = food.image

    return pic_url


# 查询菜品描述
def getRemarkById(cookbook_id, menu_id):
    a = re.compile('^[0-9a-fA-F]{24}$')
    b = a.search(cookbook_id)
    if not b:
        raise BaseException('cookbook_id无效')
    remark = ""
    if cookbook_id is None or cookbook_id is "" or menu_id is None or menu_id is "":
        raise BaseException('菜谱参数无效')
    else:
        cookbook = CookBook.objects.get(id=cookbook_id)
        menuList = cookbook.menu
        for food in menuList:
            if food.id == menu_id:
                remark = food.remarks

    return remark


# 查询菜谱状态
def getcStautsById(cookbook_id):
    a = re.compile('^[0-9a-fA-F]{24}$')
    b = a.search(cookbook_id)
    if not b:
        raise BaseException('cookbook_id无效')
    remark = ""
    if cookbook_id is None or cookbook_id is "":
        raise BaseException('菜谱参数无效')
    else:
        cookbook = CookBook.objects.get(id=cookbook_id)
        cStatus = cookbook.status
    return cStatus


# 查询菜品状态
def getmStatusById(cookbook_id, menu_id):
    a = re.compile('^[0-9a-fA-F]{24}$')
    b = a.search(cookbook_id)
    if not b:
        raise BaseException('cookbook_id无效')
    remark = ""
    if cookbook_id is None or cookbook_id is "" or menu_id is None or menu_id is "":
        raise BaseException('菜谱参数无效')
    else:
        cookbook = CookBook.objects.get(id=cookbook_id)
        menuList = cookbook.menu
        for food in menuList:
            if food.id == menu_id:
                mStatus = food.status

    return mStatus


# 订单状态已完成定时器
def fun_timer():
    timeNow = int(time.time())
    orders = Orders.objects.filter(status="待收货")
    for order in orders:
        a = order.time_end
        timeArray = time.strptime(a, "%Y-%m-%d %H:%M:%S")
        timeStamp = int(time.mktime(timeArray))
        gap = timeNow-timeStamp
        if gap == 10800 or gap > 10800:
            order.status = "已完成"
            order.save()
    global timer  #定义变量
    timer = threading.Timer(1800, fun_timer)   #一小时调用一次函数
    #定时器构造函数主要有2个参数，第一个参数为时间，第二个参数为函数名
    timer.start()    #启用定时器


# 屏蔽csrf保护
@csrf_exempt
def OrderQuery(request):
    if request.method == 'GET':
        user_id = request.GET.get("user_id", "")
        order_num = request.GET.get("order_num", "")
        community = request.GET.get("community", "")
        date = request.GET.get("date", "")
        print(date)
        print(type(date))
        # 查询对象
        if user_id is "" and order_num is not "" and community is "" and date is "":
            queryOrder = Orders.objects.filter(order_num=order_num).order_by("-time_end")
        if user_id is not "" and order_num is "" and community is "" and date is "":
            queryOrder = Orders.objects.filter(user_id=user_id).order_by("-time_end")
        if user_id is "" and order_num is "" and community is not "" and date is "":
            queryOrder = Orders.objects.filter(community=community).order_by("-time_end")
        if user_id is "" and order_num is "" and community is ""and date is "":
            mstatus_error = CodeModeDTO(CodeModeDTO.PARAMETER_ERROR, '查单参数有误', "")
            return HttpResponse(mstatus_error.to_json(), content_type='application/json,charset=utf-8')
        if user_id is not"" and order_num is not "" and community is "" and date is "":
            queryOrder = Orders.objects.filter(order_num=order_num, user_id=user_id).order_by("-time_end")
        if user_id is "" and order_num is "" and community is not"" and date is not "":
            b = date + " " + "00:00:00"
            c = date + " " + "23:59:59"
            print(b)
            print(type(b))
            d = datetime.strptime(b, "%Y-%m-%d %H:%M:%S")
            e = datetime.strptime(c, "%Y-%m-%d %H:%M:%S")
            queryOrder = Orders.objects.filter(community=community, pay_time__gte=d).filter(pay_time__lte=e).order_by("-time_end")
        if user_id is "" and order_num is "" and community is "" and date is not "":
            b = date + " " + "00:00:00"
            c = date + " " + "23:59:59"
            print(b)
            print(type(b))
            d = datetime.strptime(b, "%Y-%m-%d %H:%M:%S")
            e = datetime.strptime(c, "%Y-%m-%d %H:%M:%S")
            queryOrder = Orders.objects.filter(pay_time__gte=d).filter(pay_time__lte=e).order_by("-time_end")
            print(query_set_to_list(queryOrder))



    # 转化为数据列表
    orderInfo = query_set_to_list(queryOrder)
    # 规范接口返回格式 即CodeModeDTO（code,message,data）
    #  :param code: int 返回码
    #  :param message: string 返回消息
    #  :param data: obj 返回的数据
    order_a = CodeModeDTO(CodeModeDTO.SUCCESS, '查询成功', orderInfo)
    # 指定返回类型为json
    return HttpResponse(order_a.to_json(), content_type='application/json,charset=utf-8')


# 生成订单
# 屏蔽csrf保护
@csrf_exempt
def OrderCreat(request):
    preorder_data = {}
    if request.method == 'POST':
        # 获取客户端IP
        user_ip = ''
        if 'HTTP_X_FORWARDED_FOR' in request.META:
            user_ip = request.META['HTTP_X_FORWARDED_FOR']
        else:
            user_ip = request.META['REMOTE_ADDR']
        # 获取请求的数据
        dataString = request.body
        data = json.loads(dataString.decode('utf-8'))
        # 将请求的数据存入order
        order = Orders()
        order["status"] = "待付款"
        order["result_code"] = ""
        order["total_fee"] = 0
        order["transaction_id"] = ""
        order["time_end"] = ""
        order["community"] = data["community"]
        order["point"] = data["point"]
        order["discount"] = data["discount"]
        order["room_num"] = data["room_num"]
        order["delivery_name"] = data["delivery_name"]
        order["delivery_tel"] = data["delivery_tel"]
        order["order_num"] = ''.join(str(uuid.uuid1()).split('-'))
        order["user_id"] = data["user_id"]
        order["point_address"] = data["point_address"]
        order["open_id"] = data["open_id"]
        order["remarks"] = data["remarks"]
        order["cookbook_id"] = data["cookbook_id"]
        cookbook_id = order["cookbook_id"]
        orderPayment = 0
        cstatus = getcStautsById(cookbook_id)
        if cstatus == "Open":
            # 遍历菜谱
            for menu in data["menus"]:
                a = Menu()
                a["amount"] = menu["amount"]
                menu_id = menu["menu_id"]
                mstatus = getmStatusById(cookbook_id, menu_id)
                if mstatus == "Open":
                    try:
                        a["price"] = getPriceById(cookbook_id, menu_id)
                        a["name"] = getNameById(cookbook_id, menu_id)
                        a["pic_url"] = getUrlById(cookbook_id, menu_id)
                        a["remark"] = getRemarkById(cookbook_id, menu_id)
                    except BaseException as e:
                        ID_error = CodeModeDTO(CodeModeDTO.PARAMETER_ERROR, str(e), '')
                        return HttpResponse(ID_error.to_json(), content_type='application/json,charset=utf-8')
                    a["menu_id"]=menu_id
                    order.menus.append(a)
                    pay = int(a["amount"]) * a["price"]
                    orderPayment = orderPayment + pay
                else:
                    mstatus_error = CodeModeDTO(CodeModeDTO.PARAMETER_ERROR, '菜品状态有误', "")
                    return HttpResponse(mstatus_error.to_json(), content_type='application/json,charset=utf-8')
        else:
            cstatus_error = CodeModeDTO(CodeModeDTO.PARAMETER_ERROR, '菜谱状态有误', "")
            return HttpResponse(cstatus_error.to_json(), content_type='application/json,charset=utf-8')
        if orderPayment == data["payment"]:
            order["payment"] = round(orderPayment,2)
        else:
            payment_error = CodeModeDTO(CodeModeDTO.PARAMETER_ERROR, '支付金额有误', "")
            return HttpResponse(payment_error.to_json(), content_type='application/json,charset=utf-8')
        order.save()
        wechatorder_data = {
            'appid': APPID,
            'mch_id': MCH_ID,
            'device_info': 'WEB',
            'nonce_str':  ''.join(str(uuid.uuid4()).split('-')),
            'sign_type': 'MD5',
            'body': '河北九度软件科技有限公司-食品',
            'out_trade_no': order.order_num,
            'fee_type': 'CNY',
            'total_fee': int(order.payment*100),
            'spbill_create_ip': user_ip,
            'notify_url': 'http://tanqin520.udutech.com:8001/order/payInfo',
            'trade_type': 'JSAPI',
            'openid': order.open_id
        }
        wechatorder_datadict = dict(sorted(wechatorder_data.items()))
        wechatorder_datastring = []

        for key in wechatorder_datadict:
            item = key+'='+str(wechatorder_datadict[key])
            wechatorder_datastring.append(item)
        orderString = '&'.join(wechatorder_datastring)
        stringSignTemp = orderString + "&key=UDUsoft78jiudu123tanqin520UDUsof"
        sign = hashlib.md5(stringSignTemp.encode(encoding='UTF-8')).hexdigest().upper()
        wechatorder_data["sign"] = sign
        orderdata = xmltodict.unparse({'xml': wechatorder_data})
        r = requests.post('https://api.mch.weixin.qq.com/pay/unifiedorder', data=orderdata.encode("'utf-8'"))
        text = r.content.decode("utf-8")
        textXml = xmltodict.parse(text)["xml"]
        return_code = textXml["return_code"]
        return_msg = textXml["return_msg"]
        if return_code == "SUCCESS":
            prepay_id = textXml["prepay_id"]
            preorder_data = {
                'appId': APPID,
                'timeStamp': str(time.time()),
                'nonceStr': ''.join(str(uuid.uuid4()).split('-')),
                'package': 'prepay_id=' + prepay_id,
                'signType': 'MD5'
            }
            preorder_datadict = dict(sorted(preorder_data.items()))
            preorder_datastring = []
            for key in preorder_datadict:
                item = key+'='+preorder_datadict[key]
                preorder_datastring.append(item)
            preorderString = '&'.join(preorder_datastring)
            Pre_stringSignTemp = preorderString + "&key=UDUsoft78jiudu123tanqin520UDUsof"
            paySign = hashlib.md5(Pre_stringSignTemp.encode(encoding='UTF-8')).hexdigest().upper()
            preorder_data["paySign"] = paySign
            preorder_data["order_num"] = order["order_num"]
        else:
            preorder_error = CodeModeDTO(CodeModeDTO.PARAMETER_ERROR, '微信统一下单失败', return_msg)
            return HttpResponse(preorder_error.to_json(), content_type='application/json,charset=utf-8')

    order_b = CodeModeDTO(CodeModeDTO.SUCCESS, '下单成功请付款', preorder_data)
    return HttpResponse(order_b.to_json(), content_type='application/json,charset=utf-8')

@csrf_exempt
def payInfo(request):
    payData = request.body
    textDict = xmltodict.parse(payData)["xml"]
    return_code = textDict["return_code"]
    if return_code == 'SUCCESS':
        payresult = {
            'result_code': textDict["result_code"],
            'total_fee': textDict["total_fee"],
            'out_trade_no': textDict["out_trade_no"],
            'transaction_id': textDict["transaction_id"],
            'time_end': textDict["time_end"]
        }
        payOrder = Orders.objects.filter(order_num=payresult["out_trade_no"])
        payOrder_this = payOrder[0]
        payOrder_this.result_code = payresult["result_code"]
        payOrder_this.total_fee = payresult["total_fee"]
        payOrder_this.transaction_id = payresult["transaction_id"]
        t = payresult["time_end"]
        timeStruct = time.strptime(t, "%Y%m%d%H%M%S")
        strTime = time.strftime("%Y-%m-%d %H:%M:%S", timeStruct)
        payOrder_this.time_end = strTime
        payOrder_this.status = "待收货"
        payOrder_this.save()
        returnWechat = {
            "return_code": "<![CDATA[SUCCESS]]>",
            "return_msg": "<![CDATA[OK]]>"
        }
    returnWechatXml = xmltodict.unparse({'xml': returnWechat})
    returnWechatXml_html = html.unescape(returnWechatXml)
    return HttpResponse(returnWechatXml_html, content_type='charset=utf-8')


@csrf_exempt
def payInfoFront(request):
    if request.method == 'GET':
        order_num = request.GET.get("order_num", "")
        # 查询对象
        if order_num is not "":
            queryOrderSet = Orders.objects.filter(order_num=order_num)
            queryOrder = queryOrderSet[0]
            payInfoFront_msg = {
                'result_code': queryOrder.result_code,
                'total_fee': queryOrder.total_fee,
                'transaction_id': queryOrder.transaction_id,
                'time_end': queryOrder.time_end
            }
            print(type(payInfoFront_msg["time_end"]))
        else:
            order_c = CodeModeDTO(CodeModeDTO.PARAMETER_ERROR, '请输入订单号 ', '')
            return HttpResponse(order_c.to_json(), content_type='application/json,charset=utf-8')
    order_d = CodeModeDTO(CodeModeDTO.SUCCESS, '支付结果通知', payInfoFront_msg)
    return HttpResponse(order_d.to_json(), content_type='application/json,charset=utf-8')



